﻿using Coldairarrow.Entity.Base_Manage;
using Coldairarrow.IBusiness;
using Coldairarrow.Util;
using EFCore.Sharding;
using Microsoft.Data.SqlClient;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyModel;
using Microsoft.Extensions.Hosting;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data;
using System.Data.Common;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.Loader;
using System.Text;
using System.Threading.Tasks;
using Coldairarrow.Entity;
using Coldairarrow.Util.Utilities;
using Coldairarrow.Entity.DomainModels.Sys;

namespace Coldairarrow.Business.Base_Manage
{
    public class BuildSuperCodeBusiness : BaseBusiness<Sys_TableInfo>, IBuildSuperCodeBusiness, ITransientDependency
    {
        private readonly IOperator _operator;
        public BuildSuperCodeBusiness(IDbAccessor db, IOperator @operator, IHostEnvironment evn)
            : base(db)
        {
            _operator = @operator;
            var projectPath = evn.ContentRootPath;
            _solutionPath = Directory.GetParent(projectPath).ToString();
        }
        private int totalWidth = 0;
        private int totalCol = 0;
        private string webProject = null;
        private string apiNameSpace = null;
        private string startName = "";
        private static readonly List<string> ignoreProperties =
            new List<string> { "Id", "CreateTime", "CreatorId", "CreatorRealName", "Modifier", "ModifyID", "ModifyDate", "Deleted" };
        private static string[] formType = new string[] { "bigint", "int", "decimal", "float", "byte" };
        private string StratName
        {
            get
            {
                if (startName == "")
                {
                    startName = WebProject.Substring(0, webProject.IndexOf('.'));
                }
                return startName;
            }
        }
        #region 外部接口

        /// <summary>
        /// 获取生成配置的树开菜单
        /// </summary>
        /// <returns></returns>
        public async Task<object> GetTableTree()
        {
            var treeData = await GetIQueryable()
                .Select(c => new
                {
                    id = c.Table_Id,
                    pId = c.ParentId,
                    parentId = c.ParentId,
                    name = c.ColumnCNName,
                    orderNo = c.OrderNo
                }).OrderByDescending(c => c.orderNo).ToListAsync();
            var treeList = treeData.Select(a => new
            {
                a.id,
                a.pId,
                a.parentId,
                a.name,
                isParent = treeData.Select(x => x.pId).Contains(a.id)
            });
            string startsWith = WebProject.Substring(0, WebProject.IndexOf('.'));
            //return (treeList.Count() == 0 ? "[]" : treeList.ToJson() ?? "", ProjectPath.GetProjectFileName(startsWith));

            return (treeList.Count() == 0 ? "[]" : treeList);
        }

        public async Task<List<BuilderCodeTreeDTO>> GetBuildListTree()
        {
            var where = LinqHelper.True<Sys_TableInfo>();
            //if (!input.parentId.IsNullOrEmpty())
            //    where = where.And(x => x.ParentId.ToString() == input.parentId);

            var list = await GetIQueryable().Where(where).ToListAsync();
            var treeList = list
                .Select(x => new BuilderCodeTreeDTO
                {
                    Id = x.Table_Id.ToString(),
                    ParentId = x.ParentId.ToString(),
                    Text = x.ColumnCNName,
                    Value = x.Table_Id.ToString(),
                    orderNo = x.OrderNo
                }).OrderByDescending(c => c.orderNo).ToList();

            return TreeHelper.BuildTree(treeList);
        }

        public async Task<WebResponseContent> SaveEidt(Sys_TableInfo sysTableInfo)
        {
            //明细表判断
            WebResponseContent webResponse = ValidColumnString(sysTableInfo);
            try
            {
                if (!webResponse.Status) return webResponse;
                //禁止选择上级角色为自己
                if (sysTableInfo.Table_Id == sysTableInfo.ParentId)
                {
                    return WebResponseContent.Instance.Error($"父级id不能为自己");
                }
                if (sysTableInfo.TableColumns != null && sysTableInfo.TableColumns.Any(x => !string.IsNullOrEmpty(x.DropNo) && x.ColumnName == sysTableInfo.ExpressField))
                {
                    return WebResponseContent.Instance.Error($"不能将字段【{sysTableInfo.ExpressField}】设置为快捷编辑,因为已经设置了数据源");
                }
                if (sysTableInfo.TableColumns != null)
                {
                    sysTableInfo.TableColumns.ForEach(x =>
                    {
                        x.TableName = sysTableInfo.TableName;
                    });
                }
                sysTableInfo.TableColumns?.ForEach(x =>
                {
                    if (x.IsReadDataset == null)
                    {
                        x.IsReadDataset = 0;
                    }
                });
                var tablemodel = Db.GetIQueryable<Sys_TableInfo>().Where(x => x.TableName==sysTableInfo.TableName).FirstOrDefault();
                if (tablemodel.IsNullOrEmpty())
                {
                    int i = await Db.InsertAsync(sysTableInfo);
                    if (i>0)
                    {
                        var model = Db.GetIQueryable<Sys_TableColumn>()
                            .Where(x => x.Table_Id.Equals(sysTableInfo.Table_Id)).FirstOrDefault();
                        if (model !=null)
                        {
                            await Db.UpdateAsync(sysTableInfo.TableColumns);
                        }
                        else
                        {
                            await Db.InsertAsync(sysTableInfo.TableColumns);
                        }
                    }
                }
                else
                {
                    int j = await Db.UpdateAsync(sysTableInfo);
                    if (j>0)
                    {
                        var model = Db.GetIQueryable<Sys_TableColumn>()
                        .Where(x => x.Table_Id.Equals(sysTableInfo.Table_Id)).FirstOrDefault();
                        if (model !=null)
                        {
                            await Db.UpdateAsync(sysTableInfo.TableColumns);
                        }
                        else
                        {
                            await Db.InsertAsync(sysTableInfo.TableColumns);
                        }
                    }
                }

            }
            catch (Exception ex)
            {

                throw new Exception(ex.Message);
            }
            return webResponse;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entities"></param>
        /// <param name="isNull"></param>
        private async Task InsertOrUpdate<T>(List<T> entities,bool isNull)
        {
            if (!isNull)
            {
                await Db.UpdateAsync(entities);
            }
            else
            {
                await Db.InsertAsync(entities);
            }
        }

        private WebResponseContent ValidColumnString(Sys_TableInfo tableInfo)
        {
            WebResponseContent webResponse = new WebResponseContent(true);
            if (tableInfo.TableColumns == null || tableInfo.TableColumns.Count == 0) return webResponse;

            if (!string.IsNullOrEmpty(tableInfo.DetailName))
            {
                Sys_TableColumn mainTableColumn = tableInfo.TableColumns
                     .Where(x => x.IsKey == 1)
                     // .Select(s => s.ColumnName)
                     .FirstOrDefault();
                if (mainTableColumn == null)
                    return webResponse.Error($"请勾选表[{tableInfo.TableName}]的主键");
                string key = mainTableColumn.ColumnName;

                //明细表外键列的配置信息
                Sys_TableColumn tableColumn = Db.GetIQueryable<Sys_TableColumn>()
                    .Where(x => x.TableName == tableInfo.DetailName && x.ColumnName == key)?.FirstOrDefault();
                if (tableColumn == null)
                    return webResponse.Error($"明细表必须包括[{tableInfo.TableName}]主键字段[{key}]");
                if (mainTableColumn.ColumnType?.ToLower() != tableColumn.ColumnType?.ToLower())
                {
                    return webResponse.Error($"明细表的字段[{tableColumn.ColumnName}]类型必须与主表的主键的类型相同");
                }
                //if (mainTableColumn.ColumnType?.ToLower() == "string"
                //    && tableColumn.Maxlength != 36)
                //{
                //    return webResponse.Error($"主表主键类型为Guid，明细表[{tableInfo.DetailName}]配置的字段[{key}]长度必须是36，请重将明细表字段[{key}]长度设置为36，点击保存与生成Model");
                //}
            }
            return webResponse;
        }

        /// <summary>
        /// 界面加载表的配置信息
        /// </summary>
        /// <param name="parentId"></param>
        /// <param name="tableName"></param>
        /// <param name="columnCNName"></param>
        /// <param name="nameSpace"></param>
        /// <param name="foldername"></param>
        /// <param name="tableId"></param>
        /// <param name="isTreeLoad">true只加载表数据</param>
        /// <returns></returns>
        public async Task<object> LoadTable(int parentId, string tableName, string columnCNName, string nameSpace, string foldername, int tableId, bool isTreeLoad)
        {
            if (!_operator.IsAdmin() && !isTreeLoad)
            {
                throw new Exception("只有超级管理员才能进行此操作");
            }
            tableId = await InitTable(parentId, tableName?.Trim(), columnCNName, nameSpace, foldername, tableId, isTreeLoad);
            Sys_TableInfo tableInfo = await Db.GetIQueryable<Sys_TableInfo>()
                .Where(x => x.Table_Id == tableId).Include(c => c.TableColumns)
                .FirstOrDefaultAsync();
            if (tableInfo.TableColumns != null)
            {
                tableInfo.TableColumns = tableInfo.TableColumns.OrderByDescending(x => x.OrderNo).ToList();
            }
            return tableInfo;
        }

        /// <summary>
        /// 界面加载表的配置信息
        /// </summary>
        /// <param name="parentId"></param>
        /// <param name="tableName"></param>
        /// <param name="columnCNName"></param>
        /// <param name="nameSpace"></param>
        /// <param name="foldername"></param>
        /// <param name="tableId"></param>
        /// <param name="isTreeLoad">true只加载表数据</param>
        /// <returns></returns>
        public async Task<object> LoadTable(TabeInfo input)
        {
            int parentId = input.parentId;
            string tableName = input.tableName;
            string columnCNName = input.columnCNName;
            string nameSpace = input.nameSpace;
            string foldername = input.foldername;
            int tableId = input.table_Id;
            bool isTreeLoad = input.isTreeLoad;
            if (!_operator.IsAdmin() && !isTreeLoad)
            {
                throw new Exception("只有超级管理员才能进行此操作");
            }
            tableId = await InitTable(parentId, tableName?.Trim(), columnCNName, nameSpace, foldername, tableId, isTreeLoad);
            Sys_TableInfo tableInfo = await Db.GetIQueryable<Sys_TableInfo>()
                .Where(x => x.Table_Id == tableId).Include(c => c.TableColumns)
                .FirstOrDefaultAsync();
            if (tableInfo !=null)
            {
                if (tableInfo.TableColumns != null)
                {
                    tableInfo.TableColumns = tableInfo.TableColumns.OrderByDescending(x => x.OrderNo).ToList();
                }
            }
      
            return tableInfo;
        }
        /// <summary>
        /// 初始化生成配置对应表的数据信息
        /// </summary>
        /// <param name="parentId"></param>
        /// <param name="tableName"></param>
        /// <param name="columnCNName"></param>
        /// <param name="nameSpace"></param>
        /// <param name="foldername"></param>
        /// <param name="tableId"></param>
        /// <param name="isTreeLoad"></param>
        /// <returns></returns>
        private async Task<int> InitTable(int parentId, string tableName, string columnCNName, string nameSpace, string foldername, int tableId, bool isTreeLoad)
        {
            _dbHelper = GetTheDbHelper();
            if (isTreeLoad)
                return tableId;
            if (string.IsNullOrEmpty(tableName))
                return -1;
            tableId = Db.GetIQueryable<Sys_TableInfo>().Where(x => x.TableName == tableName)
                .Select(e => e.Table_Id).FirstOrDefault();
            if (tableId > 0)
                return tableId;

            Sys_TableInfo tableInfo = new Sys_TableInfo()
            {
                ParentId = parentId,
                ColumnCNName = columnCNName,
                CnName = columnCNName,
                TableName = tableName,
                Namespace = nameSpace,
                FolderName = foldername,
                Enable = 1
            };
            List<Sys_TableColumn> columns = _dbHelper.GetListBySql<Sys_TableColumn>(GetCurrentSql(tableName), new List<DbParameter> { new SqlParameter("@tableName", tableName) });
            int orderNo = (columns.Count + 10) * 50;
            for (int i = 0; i < columns.Count; i++)
            {
                columns[i].OrderNo = orderNo;
                orderNo = orderNo - 50;
                columns[i].EditRowNo = 0;
            }

            SetMaxLength(columns);
            int k = await Db.InsertAsync(tableInfo);
            if (k>0)
            {
                await Db.InsertAsync(columns);
            }
            else
            {
                throw new Exception("主表数据插入失败!");
            }

            return tableInfo.Table_Id;
        }
        /// <summary>
        /// 设置界面table td单元格的宽度
        /// </summary>
        /// <param name="columns"></param>
        private void SetMaxLength(List<Sys_TableColumn> columns)
        {
            columns.ForEach(x =>
            {
                if (x.ColumnName == "DateTime"||x.ColumnName == "CreateTime")
                {
                    x.ColumnWidth = 150;
                }
                else if (x.ColumnName == "Editor"||x.ColumnName == "Modifier" || x.ColumnName == "Creator")
                {
                    x.ColumnWidth = 130;
                }
                else if (x.ColumnName == "CreatorId" ||x.ColumnName == "CreateID" || x.ColumnName == "ModifyID")
                {
                    x.ColumnWidth = 80;
                }
                else if (x.Maxlength > 200)
                {
                    x.ColumnWidth = 220;
                }
                else if (x.Maxlength > 110 && x.Maxlength <= 200)
                {
                    x.ColumnWidth = 180;
                }
                else if (x.Maxlength > 60 && x.Maxlength <= 110)
                {
                    x.ColumnWidth = 120;
                }
                else
                {
                    x.ColumnWidth = 110;
                }
            });
        }
        /// <summary>
        /// 2020.08.07完善PGSQL
        /// </summary>
        /// <param name="tableName"></param>
        /// <returns></returns>
        private string GetCurrentSql(string tableName)
        {
            string sql;
            //if (DBType.Name.ToLower() == DbCurrentType.MySql.ToString().ToLower())
            //{
            //    sql = GetMySqlStructure(tableName);
            //}
            //else if (DBType.Name.ToLower() == DbCurrentType.PgSql.ToString().ToLower())
            //{
            //    sql = GetPgSqlStructure(tableName);
            //}
            //else
            //{
            //    sql = GetSqlServerStructure(tableName);
            //}
            sql = GetSqlServerStructure(tableName);
            return sql;
        }

        /// <summary>
        /// 获取SqlServer表结构信息
        /// </summary>
        /// <param name="tableName"></param>
        /// <returns></returns>
        private string GetSqlServerStructure(string tableName)
        {
            return $@"
            SELECT TableName,
                LTRIM(RTRIM(ColumnName)) AS ColumnName,
                ColumnCNName,
                CASE WHEN ColumnType = 'uniqueidentifier' THEN 'guid'
                     WHEN ColumnType IN('smallint', 'INT') THEN 'int'
                     WHEN ColumnType = 'BIGINT' THEN 'long'
                     WHEN ColumnType IN('CHAR', 'VARCHAR', 'NVARCHAR',
                                          'text', 'xml', 'varbinary', 'image')
                     THEN 'string'
                     WHEN ColumnType IN('tinyint')
                     THEN 'byte'

                       WHEN ColumnType IN('bit') THEN 'bool'
                     WHEN ColumnType IN('time', 'date', 'DATETIME', 'smallDATETIME')
                     THEN 'DateTime'
                     WHEN ColumnType IN('smallmoney', 'DECIMAL', 'numeric',
                                          'money') THEN 'decimal'
                     WHEN ColumnType = 'float' THEN 'float'
                     ELSE 'string '
                END ColumnType,
                CASE WHEN   ColumnType IN ('NVARCHAR','NCHAR') THEN [Maxlength]/2 ELSE [Maxlength] END  [Maxlength],
                IsKey,
                CASE WHEN ColumnName IN('CreateID', 'ModifyID', '')
                          OR IsKey = 1 THEN 0
                     ELSE 1
                END AS IsDisplay ,
				1 AS IsColumnData,

              CASE   WHEN ColumnType IN('time', 'date', 'DATETIME', 'smallDATETIME') THEN 150

                     WHEN ColumnName IN('Modifier', 'Creator') THEN 130

                     WHEN ColumnType IN('int', 'bigint') OR ColumnName IN('CreateID', 'ModifyID', '') THEN 80
                     WHEN[Maxlength] < 110 AND[Maxlength] > 60 THEN 120

                     WHEN[Maxlength] < 200 AND[Maxlength] >= 110 THEN 180

                     WHEN[Maxlength] > 200 THEN 220
                     ELSE 110
                   END AS ColumnWidth ,
                0 AS OrderNo,
                --CASE WHEN IsKey = 1 OR t.[IsNull]=0 THEN 0
                --     ELSE 1 END
                t.[IsNull] AS
                 [IsNull],
            CASE WHEN IsKey = 1 THEN 1 ELSE 0 END IsReadDataset,
            CASE WHEN IsKey!=1 AND t.[IsNull] = 0 THEN 0 ELSE NULL END AS EditColNo
        FROM    (SELECT obj.name AS TableName ,
                            col.name AS ColumnName ,
                            CONVERT(NVARCHAR(100),ISNULL(ep.[value], '')) AS ColumnCNName,
                            t.name AS ColumnType ,
                           CASE WHEN  col.length<1 THEN 0 ELSE  col.length END  AS[Maxlength],
                            CASE WHEN EXISTS (SELECT   1
                                               FROM dbo.sysindexes si
                                                        INNER JOIN dbo.sysindexkeys sik ON si.id = sik.id
                                                              AND si.indid = sik.indid
                                                        INNER JOIN dbo.syscolumns sc ON sc.id = sik.id
                                                              AND sc.colid = sik.colid
                                                        INNER JOIN dbo.sysobjects so ON so.name = si.name
                                                              AND so.xtype = 'PK'
                                               WHERE sc.id = col.id
                                                        AND sc.colid = col.colid)
                                 THEN 1
                                 ELSE 0
                            END AS IsKey ,
                            CASE WHEN col.isnullable = 1 THEN 1
                                 ELSE 0
                            END AS[IsNull],
                            col.colorder
                  FROM      dbo.syscolumns col
                            LEFT JOIN dbo.systypes t ON col.xtype = t.xusertype
                           INNER JOIN dbo.sysobjects obj ON col.id = obj.id

                                                            AND obj.xtype IN ( 'U','V')
                                                          --   AND obj.status >= 01
                            LEFT JOIN dbo.syscomments comm ON col.cdefault = comm.id
                            LEFT JOIN sys.extended_properties ep ON col.id = ep.major_id
                                                              AND col.colid = ep.minor_id
                                                              AND ep.name = 'MS_Description'
                            LEFT JOIN sys.extended_properties epTwo ON obj.id = epTwo.major_id
                                                              AND epTwo.minor_id = 0
                                                              AND epTwo.name = 'MS_Description'
                  WHERE obj.name = @tableName--表名
                ) AS t
            ORDER BY t.colorder";
        }

        public async Task<WebResponseContent> DelTree(int table_Id)
        {
            if (table_Id == 0)
                return new WebResponseContent().Error("没有传入参数");
            Sys_TableInfo tableInfo = await Db.GetIQueryable<Sys_TableInfo>().Where(x => x.Table_Id == table_Id)
                .Include(c => c.TableColumns)
                .FirstOrDefaultAsync();
            if (tableInfo == null)
                return new WebResponseContent().OK();
            if (tableInfo.TableColumns != null && tableInfo.TableColumns.Count > 0)
            {
                return new WebResponseContent().Error("当前删除的节点存在表结构信息,只能删除空节点");
            }
            if (await Db.GetIQueryable<Sys_TableInfo>().Where(x => x.ParentId == table_Id).AnyAsync())
            {
                return new WebResponseContent().Error("当前删除的节点存在子节点，不能删除");
            }

            await Db.DeleteAsync(tableInfo);

            return new WebResponseContent().OK();
        }

        public async Task<object> SyncTable(string tableName)
        {
            _dbHelper = GetTheDbHelper();
            if (string.IsNullOrEmpty(tableName))
                return $"表名不能为空";
            Sys_TableInfo tableInfo = Db.GetIQueryable<Sys_TableInfo>().Where(x => x.TableName == tableName)
          .Include(o => o.TableColumns).FirstOrDefault();
            if (tableInfo == null)
                return $"未获取到【" + tableName + "】的配置信息，请使用新建功能";
            if (!string.IsNullOrEmpty(tableInfo.TableTrueName) && tableInfo.TableTrueName != tableName)
            {
                tableName = tableInfo.TableTrueName;
            }

            string sql = GetCurrentSql(tableName);
            //获取表结构
            List<Sys_TableColumn> columns = _dbHelper.GetListBySql<Sys_TableColumn>(sql, new List<DbParameter> { new SqlParameter("@tableName", tableName) });
            if (columns == null || columns.Count == 0)
                return $"未获取到【" + tableName + "】表结构信息，请确认表是否存在";

            //获取现在配置好的表结构
            List<Sys_TableColumn> detailList = tableInfo.TableColumns ?? new List<Sys_TableColumn>();
            List<Sys_TableColumn> addColumns = new List<Sys_TableColumn>();
            List<Sys_TableColumn> updateColumns = new List<Sys_TableColumn>();
            foreach (Sys_TableColumn item in columns)
            {
                Sys_TableColumn tableColumn = detailList.Where(x => x.ColumnName == item.ColumnName)
                    .FirstOrDefault();
                //新加的列
                if (tableColumn == null)
                {
                    item.TableName = tableInfo.TableName;
                    item.Table_Id = tableInfo.Table_Id;
                    addColumns.Add(item);
                    continue;
                }
                //修改了数据类库或字段长度
                if (item.ColumnType != tableColumn.ColumnType || item.Maxlength != tableColumn.Maxlength || (item.IsNull ?? 0) != (tableColumn.IsNull ?? 0))
                {
                    tableColumn.ColumnType = item.ColumnType;
                    tableColumn.Maxlength = item.Maxlength;
                    tableColumn.IsNull = item.IsNull;
                    updateColumns.Add(tableColumn);
                }
            }
            //删除的列
            List<Sys_TableColumn> delColumns = detailList.Where(a => !columns.Select(c => c.ColumnName).Contains(a.ColumnName)).ToList();
            if (addColumns.Count + delColumns.Count + updateColumns.Count == 0)
            {
                return $"【" + tableName + "】表结构未发生变化";
            }
            await Db.InsertAsync(addColumns);
            await Db.DeleteAsync(delColumns);
            await Db.UpdateAsync(updateColumns);
            return $"新加字段【{addColumns.Count}】个,删除字段【{delColumns.Count}】,修改字段【{updateColumns.Count}】";
        }

        /// <summary>
        /// 生成实体Model
        /// </summary>
        /// <param name="sysTableInfo"></param>
        /// <returns></returns>
        public async Task<WebResponseContent> CreateEntityModel(Sys_TableInfo sysTableInfo)
        {
            _dbHelper = GetTheDbHelper();
            WebResponseContent webResponse = ValidColumnString(sysTableInfo);
            if (!webResponse.Status)
                return webResponse;

            string tableName = sysTableInfo.TableName;
            webResponse = ExistsTable(tableName, sysTableInfo.TableTrueName);
            if (!webResponse.Status)
            {
                return webResponse;
            }
            if (!string.IsNullOrEmpty(sysTableInfo.TableTrueName) && sysTableInfo.TableTrueName != tableName)
            {
                tableName = sysTableInfo.TableTrueName;
            }
            string sql = GetSqlServerModelInfo();

            List<TableColumnInfo> tableColumnInfoList = _dbHelper.GetListBySql<TableColumnInfo>(sql, new List<DbParameter> { new SqlParameter("@tableName", tableName) });
            List<Sys_TableColumn> list = sysTableInfo.TableColumns;
            string msg = CreateEntityModel(list, sysTableInfo, tableColumnInfoList, 1);
            if (msg != "")
                webResponse.Message = msg;
                return webResponse;
        }
        /// <summary>
        /// 创建实体类
        /// </summary>
        /// <param name="sysColumn"></param>
        /// <param name="tableInfo"></param>
        /// <param name="createType">1、创建实体类,2创建apiinput类,3、创建apioutput类</param>
        private string CreateEntityModel(List<Sys_TableColumn> sysColumn, Sys_TableInfo tableInfo, List<TableColumnInfo> tableColumnInfoList, int createType)
        {
            string template = "DomainModel.html";
            string filePath = Path.Combine(_solutionPath, "Coldairarrow.Api", "BuildCodeTemplate\\DomianModel\\", template);
            string domainContent = FileHelper.ReadFile(filePath);
            string partialContent = domainContent;
            StringBuilder AttributeBuilder = new StringBuilder();
            sysColumn = sysColumn.OrderByDescending(c => c.OrderNo).ToList();
            bool addIgnore = false;
            foreach (Sys_TableColumn column in sysColumn)
            {
                column.ColumnType = (column.ColumnType ?? "").Trim();
                AttributeBuilder.Append("/// <summary>");
                AttributeBuilder.Append("\r\n");
                AttributeBuilder.Append("       ///" + column.ColumnCnName + "");
                AttributeBuilder.Append("\r\n");
                AttributeBuilder.Append("       /// </summary>");
                AttributeBuilder.Append("\r\n");
                if (column.IsKey == 1) { AttributeBuilder.Append(@"       [Key]" + ""); AttributeBuilder.Append("\r\n"); }
                AttributeBuilder.Append("       [Display(Name =\"" + (
                    string.IsNullOrEmpty(column.ColumnCnName) ? column.ColumnName : column.ColumnCnName
                    ) + "\")]");
                AttributeBuilder.Append("\r\n");

                TableColumnInfo tableColumnInfo = tableColumnInfoList.Where(x => x.ColumnName.ToLower().Trim() == column.ColumnName.ToLower().Trim()).FirstOrDefault();
                if (tableColumnInfo != null && (tableColumnInfo.ColumnType == "varchar" && column.Maxlength > 8000)
                             || (tableColumnInfo.ColumnType == "nvarchar" && column.Maxlength > 4000))
                {
                    column.Maxlength = 0;
                }

                if (column.ColumnType == "string" && column.Maxlength > 0 && column.Maxlength < 8000)
                {

                    AttributeBuilder.Append("       [MaxLength(" + column.Maxlength + ")]");
                    AttributeBuilder.Append("\r\n");
                }
                //不是数据列的，返回页面数据前不包含此列的数据
                if (column.IsColumnData == 0 && createType == 1)
                {
                    addIgnore = true;
                    AttributeBuilder.Append("       [JsonIgnore]");
                    AttributeBuilder.Append("\r\n");
                }

                if (tableColumnInfo != null)
                {
                    if (!string.IsNullOrEmpty(tableColumnInfo.Prec_Scale) && !tableColumnInfo.Prec_Scale.EndsWith(",0"))
                    {
                        AttributeBuilder.Append("       [DisplayFormat(DataFormatString=\"" + tableColumnInfo.Prec_Scale + "\")]");
                        AttributeBuilder.Append("\r\n");
                    }

                    if ((column.IsKey == 1 && (column.ColumnType == "string" || column.ColumnType == "uniqueidentifier")) ||
                        tableColumnInfo.ColumnType.ToLower() == "guid"
                        )
                    {
        //                string isKey = column.IsKey==1 ? $@"
        //[Key, Column(Order = {1})]" : "";

                        AttributeBuilder.Append("       [Column(Order =1)]");
                        AttributeBuilder.Append("\r\n");
                        //tableColumnInfo.ColumnType = "uniqueidentifier";
                    }

                    string maxLength = string.Empty;
                    if (tableColumnInfo.ColumnType != "uniqueidentifier")
                    {
                        if (column.IsKey != 1 && column.ColumnType.ToLower() == "string")
                        {
                            //没有指定长度的字符串字段 ，如varchar,nvarchar，text等都默认生成varchar(max),nvarchar(max)
                            if (column.Maxlength <= 0
                                || (tableColumnInfo.ColumnType == "varchar" && column.Maxlength > 8000)
                                || (tableColumnInfo.ColumnType == "nvarchar" && column.Maxlength > 4000))
                            {
                                maxLength = "(max)";
                            }
                            else
                            {
                                maxLength = "(" + column.Maxlength + ")";
                            }

                        }
                    }
                    //AttributeBuilder.Append("       [Column(TypeName=\"" + tableColumnInfo.ColumnType + maxLength + "\")]");
                    //AttributeBuilder.Append("\r\n");

                    //if ((tableColumnInfo.ColumnType == "int" || tableColumnInfo.ColumnType == "bigint" || tableColumnInfo.ColumnType == "long") && column.ColumnType.ToLower() == "string")
                    if (tableColumnInfo.ColumnType == "int" || tableColumnInfo.ColumnType == "bigint" || tableColumnInfo.ColumnType == "long")
                    {
                        column.ColumnType = tableColumnInfo.ColumnType == "int" ? "int" : "long";
                    }
                    if (tableColumnInfo.ColumnType == "bool")
                    {
                        column.ColumnType = "bit";
                    }
                }

                if (column.EditRowNo != null)
                {
                    AttributeBuilder.Append("       [Editable(true)]");
                    AttributeBuilder.Append("\r\n");
                }
                // && column.ColumnType.ToLower() == "string"
                //if (column.IsNull == 0 || (createType == 2 && column.ApiIsNull == 0))
                //{
                //    AttributeBuilder.Append("       [Required(AllowEmptyStrings=false)]");
                //    AttributeBuilder.Append("\r\n");
                //}
                string columnType = (column.ColumnType == "Date" ? "DateTime" : column.ColumnType).Trim();
                if (tableColumnInfo?.ColumnType?.ToLower() == "guid")
                {
                    columnType = "Guid";
                }
                if (column.ColumnType.ToLower() != "string" && column.IsNull == 1)
                {
                    columnType = columnType + "?";
                }
                //如果主键是string,则默认为是Guid或者使用的是mysql数据，字段类型是字符串并且长度是36则默认为是Guid
                if ((column.IsKey == 1
                    && (column.ColumnType == "string"
                       || column.ColumnType == "uniqueidentifier"))
                       || column.ColumnType == "guid"
                   )
                {
                    columnType = "string" + (column.IsNull == 1 ? "?" : "");
                }
                AttributeBuilder.Append("       public " + columnType + " " + column.ColumnName + " { get; set; }");
                AttributeBuilder.Append("\r\n\r\n       ");
            }
            if (!string.IsNullOrEmpty(tableInfo.DetailName) && createType == 1)
            {
                AttributeBuilder.Append("[Display(Name =\"" + tableInfo.DetailCnName + "\")]");
                AttributeBuilder.Append("\r\n       ");
                //增加明细表属性的ForeignKey配置
                AttributeBuilder.Append("[ForeignKey(\"" + sysColumn.Where(x => x.IsKey == 1).FirstOrDefault().ColumnName + "\")]");
                AttributeBuilder.Append("\r\n       ");
                AttributeBuilder.Append("public List<" + tableInfo.DetailName + "> " + tableInfo.DetailName + " { get; set; }");
                AttributeBuilder.Append("\r\n");
            }
            if (addIgnore)
            {
                domainContent = "using Newtonsoft.Json;\r\n" + domainContent + "\r\n";
            }
            //获取的是本地开发代码所在目录，不是布后的目录
            string mapPath = ProjectPath.GetProjectDirectoryInfo()?.FullName; //new DirectoryInfo(("~/").MapPath()).Parent.FullName;
                                                                              //  string folderPath= string.Format("\\VOL.Framework.Core.\\DomainModels\\{0}\\", foldername);
            if (string.IsNullOrEmpty(mapPath))
            {
                return "未找到生成的目录!";
            }
            domainContent = domainContent.Replace("{TableName}", tableInfo.TableName).Replace("{AttributeList}", AttributeBuilder.ToString()).Replace("{StartName}", StratName).Replace("{DomainModels}", tableInfo.FolderName);

            List<string> entityAttribute = new List<string>();
            entityAttribute.Add("TableCnName = \"" + tableInfo.ColumnCNName + "\"");
            if (!string.IsNullOrEmpty(tableInfo.TableTrueName))
            {
                entityAttribute.Add("TableName = \"" + tableInfo.TableTrueName + "\"");
            }
            if (!string.IsNullOrEmpty(tableInfo.DetailName))
            {
                string typeArr = " new Type[] { typeof(" + string.Join("),typeof(", tableInfo.DetailName.Split(',')) + ")}";
                entityAttribute.Add("DetailTable = " + typeArr + "");
            }
            if (!string.IsNullOrEmpty(tableInfo.DetailCnName))
            {
                entityAttribute.Add("DetailTableCnName = \"" + tableInfo.DetailCnName + "\"");
            }
            if (!string.IsNullOrEmpty(tableInfo.DBServer) && createType == 1)
            {
                entityAttribute.Add("DBServer = \"" + tableInfo.DBServer + "\"");
            }
            string modelNameSpace = StratName + ".Entity";
            string tableAttr = string.Join(",", entityAttribute);
            if (tableAttr != "")
            {
                tableAttr = "[Entity(" + tableAttr + ")]";
            }

            if (!string.IsNullOrEmpty(tableInfo.TableTrueName) && tableInfo.TableName != tableInfo.TableTrueName)
            {
                string tableTrueName = tableInfo.TableTrueName;      
                tableAttr = tableAttr + "\r\n[Table(\"" + tableInfo.TableTrueName + "\")]";
            }
            domainContent = domainContent.Replace("{AttributeManager}", tableAttr).Replace("{Namespace}", modelNameSpace);

            string folderName = tableInfo.FolderName;
            string tableName = tableInfo.TableName;
            string nameSpace = $@"Coldairarrow.Entity.{folderName}";
            string NewmapPath = Path.Combine(_solutionPath, "Coldairarrow.Entity");
            string modelPath = $"{NewmapPath}\\{folderName}\\";
            FileHelper.WriteFile(modelPath, tableName + ".cs", domainContent);

            return "创建成功!";
        }


        /// <summary>
        /// 获取SqlServer表结构信息
        /// </summary>
        /// <returns></returns>
        private string GetSqlServerModelInfo()
        {
            return $@"
	SELECT CASE WHEN t.ColumnType IN ('DECIMAL','smallmoney','money') THEN 
                    CONVERT(VARCHAR(30),t.Prec)+','+CONVERT(VARCHAR(30),t.Scale)  ELSE ''
                     END 
                    AS Prec_Scale,t.ColumnType,t.ColumnName
                      FROM (
                    SELECT col.prec AS  'Prec',col.scale AS 'Scale',t.name AS ColumnType,col.name AS ColumnName FROM          dbo.syscolumns col
                                                LEFT  JOIN dbo.systypes t ON col.xtype = t.xusertype
                                                INNER JOIN dbo.sysobjects obj ON col.id = obj.id
                                                                                 AND obj.xtype IN ('U','V')
                                                                                 AND obj.status >= 0
                                                LEFT  JOIN dbo.syscomments comm ON col.cdefault = comm.id
                                                LEFT  JOIN sys.extended_properties ep ON col.id = ep.major_id
                                                                                  AND col.colid = ep.minor_id
                                                                                  AND ep.name = 'MS_Description'
                                                LEFT  JOIN sys.extended_properties epTwo ON obj.id = epTwo.major_id
                                                                                  AND epTwo.minor_id = 0
                                                                                  AND epTwo.name = 'MS_Description'
                                      WHERE     obj.name =@tableName) AS t";
        }

        private WebResponseContent ExistsTable(string tableName, string tableTrueName)
        {
            WebResponseContent webResponse = new WebResponseContent(true);
            //如果是第一次创建model，此处反射获取到的是已经缓存过的文件，必须重新运行项目否则新增的文件无法做判断文件是否创建，需要重新做反射实际文件，待修改...
            var compilationLibrary = DependencyContext
                .Default
                .CompileLibraries
                .Where(x => !x.Serviceable && x.Type == "project");
            foreach (var _compilation in compilationLibrary)
            {
                try
                {
                    foreach (var entity in AssemblyLoadContext.Default
                .LoadFromAssemblyName(new AssemblyName(_compilation.Name))
                .GetTypes().Where(x => x.GetTypeInfo().BaseType != null
                    && x.BaseType == typeof(BaseEntity)))
                    {
                        if (entity.Name == tableTrueName && !string.IsNullOrEmpty(tableName) && tableName != tableTrueName)
                            return webResponse.Error($"实际表名【{tableTrueName }】已创建实体，不能创建别名【{tableName}】实体");

                        if (entity.Name != tableName)
                        {
                            var tableAttr = entity.GetCustomAttribute<TableAttribute>();
                            if (tableAttr != null && tableAttr.Name == tableTrueName)
                            {
                                return webResponse.Error($"实际表名【{tableTrueName }】已被【{entity.Name}】创建建实体,不能创建别名【{tableName}】实体,请将别名更换为【{entity.Name}】");
                            }
                        }
                    }
                }
                catch (Exception ex)
                {

                    Console.WriteLine("查找文件异常：" + ex.Message);
                }
            }
            return webResponse;

        }

        private string WebProject
        {
            get
            {
                if (webProject != null)
                    return webProject;
                webProject = ProjectPath.GetLastIndexOfDirectoryName(".Api") ?? ProjectPath.GetLastIndexOfDirectoryName("Api") ?? ProjectPath.GetLastIndexOfDirectoryName(".Web");
                if (webProject == null)
                {
                    throw new Exception("未获取到以.WebApi结尾的项目名称,无法创建页面");
                }
                return webProject;
            }
        }

        #endregion

        #region 私有成员

        /// <summary>
        /// 实体需要引用的额外命名空间
        /// </summary>
        protected string _extraUsingNamespace { get; set; } = string.Empty;

        protected string Newtonsoft { get; set; } = string.Empty;
        private string _areaName { get; set; }

        readonly string _solutionPath;
        private DbHelper _dbHelper { get; set; }
        public class DBType
        {
            public static string Name { get; set; }
        }

        private DbHelper GetTheDbHelper()
        {
            var theLink = @"Data Source=192.168.0.132;Database=MEGA_ConsignmentPaint;User ID=sa;Password=123456;MultipleActiveResultSets=true; ";
            DbHelper dbHelper = DbHelperFactory.GetDbHelper(DatabaseType.SqlServer, theLink);

            return dbHelper;
        }
        #endregion
        /// <summary>
        /// 生成Services/Repository与对应的Partial类
        /// </summary>
        /// <param name="tableName"></param>
        /// <param name="nameSpace"></param>
        /// <param name="foldername"></param>
        /// <param name="webController"></param>
        /// <param name="apiController"></param>
        /// <returns></returns>
        public string CreateServices(string tableName, string nameSpace, string foldername, bool webController, bool apiController)
        {
            var tableColumn = Db.GetIQueryable<Sys_TableColumn>().Where(x => x.TableName == tableName).FirstOrDefault();

            if (tableColumn == null)
            {
                return $"没有查到{tableName}表信息";
            }

            if (string.IsNullOrEmpty(foldername))
            {
                return $"项目文件夹不能为空";
            }

            string domainContent = "";
            //string filePath = Path.Combine(_solutionPath, "Coldairarrow.Api");
            string frameworkFolder = ProjectPath.GetProjectDirectoryInfo()?.FullName;
            string[] splitArr = nameSpace.Split('.');
            string projectName = splitArr.Length > 1 ? splitArr[splitArr.Length - 1] : splitArr[0];
            string baseOptions = "\"" + projectName + "\"," + "\"" + foldername + "\"," + "\"" + tableName + "\"";

            if (apiController)
            {

                string apiPath = ProjectPath.GetProjectDirectoryInfo().GetDirectories().Where(x => x.Name.ToLower().EndsWith(".api")).FirstOrDefault()?.FullName;
                if (string.IsNullOrEmpty(apiPath))
                {
                    return "未找到IBusiness类库,请确认是存在IBusiness类库命名以.IBusiness结尾";
                }
                apiPath += $"\\Controllers\\{projectName}\\";
                //生成Partial Api控制器
                if (!File.Exists($"{apiPath}Partial\\{tableName}Controller.cs"))
                {
                    string partialController = FileHelper.ReadFile(@"BuildCodeTemplate\\Controller\\ControllerApiPartial.html")
                       .Replace("{Namespace}", nameSpace).Replace("{TableName}", tableName).Replace("{StartName}", StratName);
                    FileHelper.WriteFile($"{apiPath}Partial\\", tableName + "Controller.cs", partialController);
                }
                //生成Api控制器
                domainContent = FileHelper.ReadFile(@"BuildCodeTemplate\\Controller\\ControllerApi.html")
                    .Replace("{Namespace}", nameSpace).Replace("{TableName}", tableName).Replace("{StartName}", StratName).Replace("{BaseOptions}", baseOptions);
                FileHelper.WriteFile(apiPath, tableName + "Controller.cs", domainContent);
            }

            //生成Repository类
            domainContent = FileHelper.ReadFile("BuildCodeTemplate\\Repositorys\\BaseRepository.html").Replace("{Namespace}", nameSpace).Replace("{TableName}", tableName).Replace("{StartName}", StratName);
            FileHelper.WriteFile(
           frameworkFolder + string.Format("\\{0}\\Repositories\\{1}\\", nameSpace, foldername)
                          , tableName + "Repository.cs", domainContent);
            //生成IDbAccessor类
            domainContent = FileHelper.ReadFile("BuildCodeTemplate\\IDbAccessors\\BaseIRepositorie.html").Replace("{Namespace}", nameSpace).Replace("{TableName}", tableName).Replace("{StartName}", StratName);
            FileHelper.WriteFile(
            frameworkFolder + string.Format("\\{0}\\IRepositories\\{1}\\", nameSpace, foldername),
                   "I" + tableName + "Repository.cs", domainContent);


            string path = $"{frameworkFolder}\\{nameSpace}\\IServices\\{ foldername}\\";

            string fileName = "I" + tableName + "Service.cs";

            //生成Partial  IService类
            if (!File.Exists(path + "Partial\\" + fileName))
            {
                domainContent = FileHelper.ReadFile("BuildCodeTemplate\\IServices\\IServiceBasePartial.html").Replace("{Namespace}", nameSpace).Replace("{TableName}", tableName).Replace("{StartName}", StratName);
                FileHelper.WriteFile(path + "Partial\\", fileName, domainContent);
            }

            //生成IService类
            domainContent = FileHelper.ReadFile("BuildCodeTemplate\\IServices\\IServiceBase.html").Replace("{Namespace}", nameSpace).Replace("{TableName}", tableName).Replace("{StartName}", StratName);
            FileHelper.WriteFile(path, fileName, domainContent);


            path = $"{frameworkFolder}\\{nameSpace}\\Services\\{ foldername}\\";
            fileName = tableName + "Service.cs";
            //生成Partial Service类
            domainContent = FileHelper.ReadFile("BuildCodeTemplate\\Services\\ServiceBasePartial.html").Replace("{Namespace}", nameSpace).Replace("{TableName}", tableName).Replace("{StartName}", StratName);
            if (!File.Exists(path + "Partial\\" + fileName))
            {
                domainContent = FileHelper.ReadFile("BuildCodeTemplate\\Services\\ServiceBasePartial.html").Replace("{Namespace}", nameSpace).Replace("{TableName}", tableName).Replace("{StartName}", StratName);
                FileHelper.WriteFile(path + "Partial\\", fileName, domainContent);
            }

            //生成Service类
            domainContent = FileHelper.ReadFile("BuildCodeTemplate\\Services\\ServiceBase.html")
                .Replace("{Namespace}", nameSpace).Replace("{TableName}", tableName)
                .Replace("{StartName}", StratName);
            FileHelper.WriteFile(path, fileName, domainContent);

            //后期实现app页面
            //if (webController)
            //{
            //    path = $"{frameworkFolder}\\{nameSpace}\\Controllers\\{ foldername}\\";
            //    fileName = tableName + "Controller.cs";
            //    //生成Partial web控制器
            //    if (!File.Exists(path + "Partial\\" + fileName))
            //    {
            //        domainContent = FileHelper.ReadFile("BuildCodeTemplate\\Controller\\ControllerPartial.html").Replace("{Namespace}", nameSpace).Replace("{TableName}", tableName).Replace("{BaseOptions}", baseOptions).Replace("{StartName}", StratName);
            //        FileHelper.WriteFile(path + "Partial\\", tableName + "Controller.cs", domainContent);
            //    }

            //    //生成web控制器
            //    domainContent = FileHelper.ReadFile("BuildCodeTemplate\\Controller\\Controller.html").Replace("{Namespace}", nameSpace).Replace("{TableName}", tableName).Replace("{BaseOptions}", baseOptions).Replace("{StartName}", StratName);
            //    FileHelper.WriteFile(path, tableName + "Controller.cs", domainContent);
            //}
            return "业务类创建成功!";
        }



        private Dictionary<string, Sys_TableColumn> _dbTableInfoDic { get; set; } = new Dictionary<string, Sys_TableColumn>();
   

        private void WriteCode(Dictionary<string, string> paramters, string templateFileName, string savePath)
        {
            string content = File.ReadAllText(Path.Combine(_solutionPath, "Coldairarrow.Api", "BuildCodeTemplate", templateFileName));
            paramters.ForEach(aParamter =>
            {
                content = content.Replace(aParamter.Key, aParamter.Value);
            });
            FileHelper.WriteTxt(content, savePath, Encoding.UTF8, FileMode.Create);
        }
        public string BuildVueCode(BuildSuperInputDTO input)
        {
            var sysTableInfo = input.sys_Table;
            if (sysTableInfo == null
                || sysTableInfo.TableColumns == null
                || sysTableInfo.TableColumns.Count == 0)
                return "提交的配置数据不完整";
            string CName = input.sys_Table.CnName;
            string linkId = input.linkId;
            int Table_Id = input.sys_Table.Table_Id;
            string areaName = input.sys_Table.FolderName;
            string aTable = input.sys_Table.TableName;
            List<int> buildTypes = input.buildTypes;
            _areaName = areaName;
            //内部成员初始化
            _dbHelper = GetTheDbHelper();
            var tableColumn = Db.GetIQueryable<Sys_TableColumn>().Where(x => x.Table_Id == Table_Id && x.TableName ==input.sys_Table.TableName).ToList();
            if (tableColumn.Count == 0)
            {
                return $"没有查到{input.sys_Table.TableName}表信息";
            }

            if (string.IsNullOrEmpty(areaName))
            {
                return $"项目文件夹不能为空";
            }
            //实体名
            string entityName = aTable;
            //业务逻辑参数名
            string busName = $"{entityName.ToFirstLowerStr()}Bus";
            //业务逻辑变量名
            string _busName = $"_{busName}";
            List<string> selectOptionsList = new List<string>();
            List<string> listColumnsList = new List<string>();
            List<string> formColumnsList = new List<string>();

            tableColumn.Where(x => !ignoreProperties.Contains(x.ColumnName)).ToList().OrderByDescending(x => x.OrderNo).ForEach(aField =>
            {
                if (_dbHelper.DbTypeStr_To_CsharpType(aField.ColumnType) == typeof(string))
                    selectOptionsList.Add(
    $"                <a-select-option key=\"{aField.ColumnName}\">{aField.ColumnCnName}</a-select-option>");
                listColumnsList.Add(
    $"  {{ title: '{aField.ColumnCnName}', dataIndex: '{aField.ColumnName}',key:'{aField.ColumnName}' width: '{aField.ColumnWidth}px' }},");
                formColumnsList.Add(
    $@"        <a-form-model-item label=""{aField.ColumnCnName}"" prop=""{aField.ColumnName}"">
          <a-input v-model=""entity.{aField.ColumnName}"" autocomplete=""off"" />
        </a-form-model-item>");
                Dictionary<string, string> renderParamters = new Dictionary<string, string>
                {
                        {$"%{nameof(areaName)}%",areaName },
                        {$"%{nameof(entityName)}%",entityName },
                        //{$"%{nameof(busName)}%",busName },
                        //{$"%{nameof(_busName)}%",_busName },
                        {$"%selectOptions%",string.Join("\r\n",selectOptionsList) },
                        {$"%listColumns%",string.Join("\r\n",listColumnsList) },
                        {$"%formColumns%",string.Join("\r\n",formColumnsList) }

                };

                string tmpFileName = string.Empty;
                string savePath = string.Empty;

                ////表格页
                //tmpFileName = "NewList.txt";
                //savePath = Path.Combine(
                //    _solutionPath,
                //    "Coldairarrow.Web",
                //    "src",
                //    "views",
                //    areaName,
                //    entityName,
                //    "List.vue");
                //WriteCode(renderParamters, tmpFileName, savePath);
                ////表单页
                //tmpFileName = "NewEditForm.txt";
                //savePath = Path.Combine(
                //    _solutionPath,
                //    "Coldairarrow.Web",
                //    "src",
                //    "views",
                //    areaName,
                //    entityName,
                //    "EditForm.vue");
                //WriteCode(renderParamters, tmpFileName, savePath);
                //表单js
                tmpFileName = "";
                savePath = Path.Combine(
                    _solutionPath,
                    "Coldairarrow.Web",
                    "src",
                    "views",
                    areaName,
                    entityName,
                    "ranks.js");
                WriteCode(renderParamters, tmpFileName, savePath);
            });

            return "";
        }


        public string BuildSuperCode(BuildSuperInputDTO input)
        {
            var sysTableInfo = input.sys_Table;
            if (sysTableInfo == null
                || sysTableInfo.TableColumns == null
                || sysTableInfo.TableColumns.Count == 0)
                return "提交的配置数据不完整";
            string CName = input.sys_Table.CnName;
            string linkId = input.linkId;
            int Table_Id = input.sys_Table.Table_Id;
            string areaName = input.sys_Table.FolderName;
            string aTable = input.sys_Table.TableName;
            List<int> buildTypes = input.buildTypes;
            _areaName = areaName;
            //内部成员初始化
            _dbHelper = GetTheDbHelper();
            var tableColumn = Db.GetIQueryable<Sys_TableColumn>().Where(x =>x.Table_Id == Table_Id && x.TableName ==input.sys_Table.TableName).ToList();
            if (tableColumn.Count == 0)
            {
                return $"没有查到{input.sys_Table.TableName}表信息";
            }

            if (string.IsNullOrEmpty(areaName))
            {
                return $"项目文件夹不能为空";
            }
            //实体名
            string entityName = aTable;
            //业务逻辑参数名
            string busName = $"{entityName.ToFirstLowerStr()}Bus";
            //业务逻辑变量名
            string _busName = $"_{busName}";
            List<string> selectOptionsList = new List<string>();
            List<string> listColumnsList = new List<string>();
            List<string> formColumnsList = new List<string>();
            tableColumn.Where(x => !ignoreProperties.Contains(x.ColumnName)).ToList().ForEach(aField =>
            {
                if (_dbHelper.DbTypeStr_To_CsharpType(aField.ColumnType) == typeof(string))
                selectOptionsList.Add(
$"                <a-select-option key=\"{aField.ColumnName}\">{aField.ColumnCnName}</a-select-option>");
            listColumnsList.Add(
$"  {{ title: '{aField.ColumnCnName}', dataIndex: '{aField.ColumnName}', width: '10%' }},");
            formColumnsList.Add(
$@"        <a-form-model-item label=""{aField.ColumnCnName}"" prop=""{aField.ColumnName}"">
          <a-input v-model=""entity.{aField.ColumnName}"" autocomplete=""off"" />
        </a-form-model-item>");
            Dictionary<string, string> renderParamters = new Dictionary<string, string>
                {
                        {$"%{nameof(areaName)}%",areaName },
                        {$"%{nameof(entityName)}%",entityName },
                        {$"%{nameof(busName)}%",busName },
                        {$"%{nameof(_busName)}%",_busName },
                        {$"%selectOptions%",string.Join("\r\n",selectOptionsList) },
                        {$"%listColumns%",string.Join("\r\n",listColumnsList) },
                        {$"%formColumns%",string.Join("\r\n",formColumnsList) }
                };

            //buildTypes,实体层=0,业务层=1,接口层=2,页面层=3
            //实体层
            //if (buildTypes.Contains(0))
            //{
            //    BuildEntity(tableColumn, CName, sysTableInfo);
            //}
            string tmpFileName = string.Empty;
            string savePath = string.Empty;
            //业务层
            if (buildTypes.Contains(1))
            {
                //接口
                tmpFileName = "NewIBusiness.txt";
                savePath = Path.Combine(
                    _solutionPath,
                    "Coldairarrow.IBusiness",
                    areaName,
                    $"I{entityName}Business.cs");
                WriteCode(renderParamters, tmpFileName, savePath);

                //实现
                tmpFileName = "NewBusiness.txt";
                savePath = Path.Combine(
                    _solutionPath,
                    "Coldairarrow.Business",
                    areaName,
                    $"{entityName}Business.cs");
                WriteCode(renderParamters, tmpFileName, savePath);
            }
                //接口层
                if (buildTypes.Contains(2))
                {
                    tmpFileName = "NewController.txt";
                    savePath = Path.Combine(
                        _solutionPath,
                        "Coldairarrow.Api",
                        "Controllers",
                        areaName,
                        $"{entityName}Controller.cs");
                    WriteCode(renderParamters, tmpFileName, savePath);
                }
               
            });

            return "";
        }


        /// <summary>
        /// 生成实体文件
        /// </summary>
        /// <param name="infos">表字段信息</param>
        /// <param name="tableName">表名</param>
        /// <param name="tableDescription">表描述信息</param>
        /// <param name="filePath">文件路径（包含文件名）</param>
        /// <param name="nameSpace">实体命名空间</param>
        /// <param name="sys_Table"></param>
        /// <param name="tableColumnInfoList"></param>
        public virtual void SaveEntityToFile(List<Sys_TableColumn> infos, string tableName, string tableDescription, string filePath, string nameSpace, Sys_TableInfo sys_Table, List<TableColumnInfo> tableColumnInfoList)
        {
            string schemaName = null;
            string properties = "";
            string schema = "";
            if (!schemaName.IsNullOrEmpty())
                schema = $@", Schema = ""{schemaName}""";
            bool addIgnore = false;
            infos.ForEach((item, index) =>
            {
                StringBuilder AttributeBuilder = new StringBuilder();
                if (item.IsKey == 1) { AttributeBuilder.Append(@"       [Key]" + ""); AttributeBuilder.Append("\r\n"); }
                AttributeBuilder.Append("       [Display(Name =\"" + (
                    string.IsNullOrEmpty(item.ColumnCnName) ? item.ColumnName : item.ColumnCnName
                    ) + "\")]");
                AttributeBuilder.Append("\r\n");
                //不是数据列的，返回页面数据前不包含此列的数据
                if (item.IsColumnData == 0)
                {
                    AttributeBuilder.Append("[JsonIgnore]");
                    AttributeBuilder.Append("\r\n");
                }
        
                TableColumnInfo tableColumnInfo = tableColumnInfoList.Where(x => x.ColumnName.ToLower().Trim() == item.ColumnName.ToLower().Trim()).FirstOrDefault();
                if (tableColumnInfo != null && (tableColumnInfo.ColumnType == "varchar" && item.Maxlength > 8000)
                             || (tableColumnInfo.ColumnType == "nvarchar" && item.Maxlength > 4000))
                {
                    item.Maxlength = 0;
                }

                if (item.ColumnType == "string" && item.Maxlength > 0 && item.Maxlength < 8000)
                {
                    AttributeBuilder.Append("[MaxLength(" + item.Maxlength + ")]");
                    AttributeBuilder.Append("\r\n");
                }
                //不是数据列的，返回页面数据前不包含此列的数据
                if (item.IsColumnData == 0)
                {
                    addIgnore = true;
                    AttributeBuilder.Append("       [JsonIgnore]");
                    AttributeBuilder.Append("\r\n");
                }
                if (tableColumnInfo != null)
                {
                    if (!string.IsNullOrEmpty(tableColumnInfo.Prec_Scale) && !tableColumnInfo.Prec_Scale.EndsWith(",0"))
                    {
                        AttributeBuilder.Append("       [DisplayFormat(DataFormatString=\"" + tableColumnInfo.Prec_Scale + "\")]");
                        AttributeBuilder.Append("\r\n");
                    }

                    if ((item.IsKey == 1 && (item.ColumnType == "string" || item.ColumnType == "uniqueidentifier")) ||
                        tableColumnInfo.ColumnType.ToLower() == "guid")
                    {
                        tableColumnInfo.ColumnType = "uniqueidentifier";
                    }

                    string maxLength = string.Empty;
                    if (tableColumnInfo.ColumnType != "uniqueidentifier")
                    {
                        if (item.IsKey != 1 && item.ColumnType.ToLower() == "string")
                        {
                            //没有指定长度的字符串字段 ，如varchar,nvarchar，text等都默认生成varchar(max),nvarchar(max)
                            if (item.Maxlength <= 0
                                || (tableColumnInfo.ColumnType == "varchar" && item.Maxlength > 8000)
                                || (tableColumnInfo.ColumnType == "nvarchar" && item.Maxlength > 4000))
                            {
                                maxLength = "(max)";
                            }
                            else
                            {
                                maxLength = "(" + item.Maxlength + ")";
                            }

                        }
                    }
                    AttributeBuilder.Append("       [Column(TypeName=\"" + tableColumnInfo.ColumnType + maxLength + "\")]");
                    AttributeBuilder.Append("\r\n");


                    //if ((tableColumnInfo.ColumnType == "int" || tableColumnInfo.ColumnType == "bigint" || tableColumnInfo.ColumnType == "long") && column.ColumnType.ToLower() == "string")
                    if (tableColumnInfo.ColumnType == "int" || tableColumnInfo.ColumnType == "bigint" || tableColumnInfo.ColumnType == "long")
                    {
                        item.ColumnType = tableColumnInfo.ColumnType == "int" ? "int" : "long";
                    }
                    if (tableColumnInfo.ColumnType == "bool")
                    {
                        item.ColumnType = "bit";
                    }
                }
                if (!string.IsNullOrEmpty(sys_Table.DetailName))
                {
                    AttributeBuilder.Append("[Display(Name =\"" + sys_Table.DetailCnName + "\")]");
                    AttributeBuilder.Append("\r\n       ");
                    //增加明细表属性的ForeignKey配置(EF Core 3.1配项)
                    AttributeBuilder.Append("[ForeignKey(\"" + infos.Where(x => x.IsKey == 1).FirstOrDefault().ColumnName + "\")]");
                    AttributeBuilder.Append("\r\n       ");
                    AttributeBuilder.Append("public List<" + sys_Table.DetailName + "> " + sys_Table.DetailName + " { get; set; }");
                    AttributeBuilder.Append("\r\n");
                }
                if (item.EditRowNo != null)
                {
                    AttributeBuilder.Append("[Editable(true)]");
                    AttributeBuilder.Append("\r\n");
                }
                string isKey = item.IsKey==1 ? $@"
        [Key, Column(Order = {index + 1})]" : "";
                Type type =_dbHelper.DbTypeStr_To_CsharpType(item.ColumnType);
                string isNullable = item.IsNull==1 && type.IsValueType ? "?" : "";
                string description = item.ColumnCnName.IsNullOrEmpty() ? item.ColumnName : item.ColumnCnName;
                
                if (item.ColumnType == "int" || item.ColumnType == "bigint" || item.ColumnType == "long")
                {
                    item.ColumnType = item.ColumnType == "int" ? "int" : "long";
                }
                if (item.ColumnType == "bool")
                {
                    item.ColumnType = "bit";
                }
                
                if (addIgnore)
                {
                    Newtonsoft = "using Newtonsoft.Json;\r\n";
                }

                string newPropertyStr =
$@"
        /// <summary>
        /// {description}
        /// </summary>{isKey}
        {AttributeBuilder}
        public {type.Name}{isNullable} {item.ColumnName} {{ get; set; }}
";
                properties += newPropertyStr;
            });
            string fileStr =
$@"using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
{_extraUsingNamespace}
{Newtonsoft}
namespace {nameSpace}
{{
    /// <summary>
    /// {tableDescription}
    /// </summary>
    [Table(""{tableName}""{schema})]
    public class {tableName}
    {{
{properties}
    }}
}}";
            FileHelper.WriteTxt(fileStr, filePath, FileMode.Create);
        }

        public class columnsDTO
        {
            public string title { get; set; }
            public string dataIndex { get; set; }
            public string key { get; set; }
            public string width { get; set; }
            public string e_type { get; set; }
            public object bind { get; set; }
        }

        public class bind
        {
            public string key { get; set; }
            public List<string> data { get; set; }
        }
        /// <summary>
        /// 生成Vue页面
        /// </summary>
        /// <param name="sysTableInfo"></param>
        /// <returns></returns>
        public string CreateVuePage(Sys_TableInfo sysTableInfo)
        {
            string SubCondition = "";
            string SubKeyword = "z@@111";
            string pageContent = null;
            string EditFormContent = null;
            string SubEditFormContent = null;
            string SearchFormContent = null;
            string ListFormContent = null;
            string TableSettContent = null;
            string tmpFileName = string.Empty;
            string savePath = string.Empty;
            string saveEditFormPath = string.Empty;
            string saveSubEditFormPath = string.Empty;
            string saveSearchFormPath = string.Empty;
            string saveListFormPath = string.Empty;
            string saveTableSettPath = string.Empty;
            string areaName = sysTableInfo.FolderName;
            string entityName = sysTableInfo.TableName;
            string SubentityName = "No";
            List<columnsDTO> listColumnsList = new List<columnsDTO>();
            List<columnsDTO> DetaillistColumnsList = new List<columnsDTO>();
            List<columnsDTO> SearchColumnsList = new List<columnsDTO>();
            List<columnsDTO> DeatilSearchColumnsList = new List<columnsDTO>();
            if (sysTableInfo == null
              || sysTableInfo.TableColumns == null
              || sysTableInfo.TableColumns.Count == 0)
                return "提交的配置数据不完整"; ;

            List<Sys_TableColumn> sysColumnList = sysTableInfo.TableColumns;
            string[] eidtTye = new string[] { "select", "selectList", "drop", "dropList", "checkbox" };
            if (sysColumnList.Exists(x => eidtTye.Contains(x.EditType) && string.IsNullOrEmpty(x.DropNo)))
            {
                return $"编辑类型为[{string.Join(',', eidtTye)}]时必须选择数据源";
            }
            if (sysColumnList.Exists(x => eidtTye.Contains(x.SearchType) && string.IsNullOrEmpty(x.DropNo)))
            {
                return $"查询类型为[{string.Join(',', eidtTye)}]时必须选择数据源";
            }

            StringBuilder sb = GetGridColumns(sysColumnList.Where(x => !ignoreProperties.Contains(x.ColumnName)).ToList(), sysTableInfo.ExpressField, false, true, app: false);

            if (sb.Length == 0) return "未获取到数据!";
         
            string columns = sb.ToString().Trim();
            columns = columns.Substring(0, columns.Length - 1);
            string key = sysColumnList.Where(c => c.IsKey == 1).Select(x => x.ColumnName).First() ?? "";

            Func<Sys_TableColumn, bool> editFunc = c => c.EditRowNo != null && c.EditRowNo > 0;

            var formFileds = sysColumnList.Where(editFunc)
                .OrderBy(o => o.EditRowNo)
                .ThenByDescending(t => t.OrderNo)
                .Select(x => new KeyValuePair<string, object>(x.ColumnName, x.EditType == "checkbox" || x.EditType == "selectList" || x.EditType == "cascader" ? new string[0] : "" as object))
                .ToList().ToDictionary(x => x.Key, x => x.Value).ToJson();

            List<List<PanelHtml>> panelHtml = new List<List<PanelHtml>>();

            List<object> list = GetSearchData(panelHtml, sysColumnList, true, app: false);
            var ignoreColumn = sysColumnList.Where(x => x.IsDisplay==0).Select(e => e.ColumnName).ToList();
            sysColumnList.Where(x => !ignoreColumn.Contains(x.ColumnName)).ToList().ForEach(aField =>
            {
                string displayType = GetDisplayType(false, "", aField.EditType, aField.ColumnType);
                listColumnsList.Add(
                    new columnsDTO()
                    {
                        dataIndex = aField.ColumnName,
                        title = aField.ColumnCnName,
                        key =aField.ColumnName,
                        width = aField.ColumnWidth+"px",
                        e_type =  aField.ColumnType == "img" ? aField.ColumnType : displayType,
                        bind = !string.IsNullOrEmpty(aField.DropNo) ? new bind() { key =aField.DropNo, data = new() { } } : new() { }
                    }
                    );
            }
);
            //默认操作列
            listColumnsList.Add(
              new columnsDTO()
              {
                  dataIndex = "action",
                  title = "操作",
                  key ="action",
                  width = "auto"
              }
              );

            sysColumnList.Where(x => !x.SearchColNo.IsNullOrEmpty()&&!x.SearchRowNo.IsNullOrEmpty()).ToList().ForEach(aField =>
            {
                string displayType = GetDisplayType(false, "", aField.EditType, aField.ColumnType);
                SearchColumnsList.Add(
                    new columnsDTO()
                    {
                        dataIndex = aField.ColumnName,
                        title = aField.ColumnCnName,
                        key =aField.ColumnName,
                        width = aField.ColumnWidth+"px",
                        e_type =  aField.ColumnType == "img" ? aField.ColumnType : displayType,
                        bind = !string.IsNullOrEmpty(aField.DropNo) ? new bind() { key =aField.DropNo, data = new() { } } : new() { }
                    }
                    );
            });
            EditFormContent = FileHelper.ReadFile("BuildCodeTemplate\\NewTemplate\\EditForm.vue");
            SubEditFormContent = FileHelper.ReadFile("BuildCodeTemplate\\NewTemplate\\SubForm.vue");
            pageContent = FileHelper.ReadFile("BuildCodeTemplate\\NewTemplate\\ranks.js");
            pageContent = pageContent.Replace("#listColumnsList", listColumnsList.ToJson().Replace("},{", "},\r\n                               {"));
            SearchFormContent = FileHelper.ReadFile("BuildCodeTemplate\\NewTemplate\\SearchForm.vue");
            ListFormContent = FileHelper.ReadFile("BuildCodeTemplate\\NewTemplate\\List.vue");
            TableSettContent = FileHelper.ReadFile("BuildCodeTemplate\\NewTemplate\\TableSett.vue");
            if (string.IsNullOrEmpty(pageContent))
            {
                return "未找到ranks.js模板文件";
            }
            if (string.IsNullOrEmpty(EditFormContent))
            {
                return "未找到EditForm.vue模板文件";
            }
            if (string.IsNullOrEmpty(SearchFormContent))
            {
                return "未找到SearchForm.vue模板文件";
            }
            if (string.IsNullOrEmpty(ListFormContent))
            {
                return "未找到List.vue模板文件";
            }
            if (string.IsNullOrEmpty(TableSettContent))
            {
                return "未找到TableSett.vue模板文件";
            }
            if (string.IsNullOrEmpty(SubEditFormContent))
            {
                return "未找到SubEditForm.vue模板文件";
            }
            Func<Sys_TableColumn, bool> func = c => c.SearchRowNo != null && c.SearchRowNo > 0;

            var searchFormFileds = sysColumnList.Where(func)
                .Select(x => new KeyValuePair<string, object>(x.ColumnName, x.SearchType == "checkbox"
                || x.SearchType == "selectList" || x.EditType == "cascader" ? new string[0] : x.SearchType == "range" ? new string[] { null, null } : "" as object))
                .ToList().ToDictionary(x => x.Key, x => x.Value).ToJson();

            pageContent = pageContent.Replace("#searchFormFileds", searchFormFileds)
                .Replace("#searchFormOptions", SearchColumnsList.ToJson() ?? ""
                .Replace("},{", "},\r\n                               {")
                .Replace("],[", "],\r\n                              [")
                );

            panelHtml = new List<List<PanelHtml>>();
            //编辑
            string formOptions = GetSearchData(panelHtml, sysColumnList.Where(editFunc).ToList(), true, true, app: false).ToJson() ?? "";
            if (sysTableInfo.Namespace.IsNullOrEmpty())
            {
                return "文件地址名称未填写";
            }
            string[] arr = sysTableInfo.Namespace.Split(".");
            string spaceFolder = (arr.Length > 1 ? arr[arr.Length - 1] : arr[0]).ToLower();
            var sorter = new SortField()
            {
                field = string.IsNullOrEmpty(sysTableInfo.SortName) ? key : sysTableInfo.SortName,
                order="desc"
            };
     
            pageContent = pageContent.Replace("#columns", columns).
                            Replace("#SortName", string.IsNullOrEmpty(sysTableInfo.SortName) ? key : sysTableInfo.SortName).
                            Replace("#sorter", sorter.ToJson()). 
                            Replace("#key", key).
                            Replace("#Foots", " ").
                            Replace("#cnName", sysTableInfo.ColumnCNName).
                            Replace("#url", "/" + sysTableInfo.TableName + "/").
                            Replace("#folder", spaceFolder).
                            Replace("#editFormFileds", formFileds).
                            Replace("#editFormOptions", formOptions.
                            Replace("},{", "},\r\n                               {").
                            Replace("],[", "],\r\n                              ["));

            //如果有明细，加载明细的数据
            if (!string.IsNullOrEmpty(sysTableInfo.DetailName))
            {
                SubentityName = sysTableInfo.DetailName;
                Sys_TableInfo detailTable = Db.GetIQueryable<Sys_TableInfo>().Where(x => x.TableName == sysTableInfo.DetailName)
                    .Include(x => x.TableColumns).FirstOrDefault();
                if (detailTable == null)
                    return $"请先生成明细表{ sysTableInfo.DetailName}的配置!";
                if (detailTable.TableColumns == null || detailTable.TableColumns.Count == 0)
                    return $"明细表{ sysTableInfo.DetailName}没有列的信息,请确认是否有列数据或列数据是否被删除!";
                var _name = detailTable.TableColumns.Where(x => x.IsImage < 4 && x.EditRowNo > 0).Select(s => s.ColumnName).FirstOrDefault();
                if (!string.IsNullOrEmpty(_name))
                {
                    return $"明细表【{_name}】字段【table显示类型】设置为了【文件或图片】,编辑行只能设置为0或不设置";
                }
                //明细列数据
                List<Sys_TableColumn> detailList = detailTable.TableColumns;


                List<List<PanelHtml>> panelHtml2 = new List<List<PanelHtml>>();

                List<object> list2 = GetSearchData(panelHtml2, detailList, true, app: false);
                //编辑
                string DetailformOptions = GetSearchData(panelHtml2, detailList.Where(editFunc).ToList(), true, true, app: false).ToJson() ?? "";
                var ignoreColumnDetail = detailList.Where(x => x.IsDisplay==0).Select(e => e.ColumnName).ToList();
                detailList.Where(x => !ignoreColumnDetail.Contains(x.ColumnName)).ToList().ForEach(aField =>
                {
                    string displayType = GetDisplayType(false, "", aField.EditType, aField.ColumnType);
                    DetaillistColumnsList.Add(
                        new columnsDTO()
                        {
                            dataIndex = aField.ColumnName,
                            title = aField.ColumnCnName,
                            key =aField.ColumnName,
                            width = aField.ColumnWidth+"px",
                            e_type =  aField.ColumnType == "img" ? aField.ColumnType : displayType,
                            bind = !string.IsNullOrEmpty(aField.DropNo) ? new bind() { key =aField.DropNo, data = new() { } } : new() { }
                        }
                        );
                }
    );
                //默认操作列
                DetaillistColumnsList.Add(
                  new columnsDTO()
                  {
                      dataIndex = "action",
                      title = "操作",
                      key ="action",
                      width = "auto"
                  }
                  );
                detailList.Where(x => !x.SearchColNo.IsNullOrEmpty()&&!x.SearchRowNo.IsNullOrEmpty()).ToList().ForEach(aField =>
                {
                    string displayType = GetDisplayType(false, "", aField.SearchType, aField.ColumnType);
                    DeatilSearchColumnsList.Add(
                        new columnsDTO()
                        {
                            dataIndex = aField.ColumnName,
                            title = aField.ColumnCnName,
                            key =aField.ColumnName,
                            width = aField.ColumnWidth+"px",
                            e_type =  aField.ColumnType == "img" ? aField.ColumnType : displayType,
                            bind = !string.IsNullOrEmpty(aField.DropNo) ? new bind() { key =aField.DropNo, data = new() { } } : new() { }
                        }
                        );
                });
                if (DeatilSearchColumnsList.Count>0)
                {
                    EditFormContent = EditFormContent.Replace("#SubCondition", DeatilSearchColumnsList[0].key);
                    SubEditFormContent = SubEditFormContent.Replace("#ParentId",DeatilSearchColumnsList[0].key);
                    EditFormContent = EditFormContent.Replace("#SubKeyword", SubKeyword);
                }
               
                
                //替换明细列数据
                //sb = GetGridColumns(detailList, detailTable.ExpressField, true, true);
                key = detailList.Where(c => c.IsKey == 1).Select(x => x.ColumnName).First();
                //columns = sb.ToString().Trim();
               // columns = columns.Substring(0, columns.Length - 1);
                pageContent = pageContent.Replace("#detailColumns", DetaillistColumnsList.ToJson()).
                    Replace("#DetailformOptions", DetailformOptions).
                    Replace("#detailCnName", detailTable.ColumnCNName).
                    Replace("#detailTable", detailTable.TableName).
                    Replace("#detailKey", detailTable.TableColumns.Where(c => c.IsKey == 1).Select(x => x.ColumnName).First()).
                    Replace("#detailSortName", string.IsNullOrEmpty(detailTable.SortName) ? key : detailTable.SortName);
            }
            else
            {
                pageContent = pageContent.Replace("#detailColumns", DetaillistColumnsList.ToJson())
                    .Replace("#detailKey", "")
                    .Replace("#detailSortName", "")
                    .Replace("#detailCnName", "")
                    .Replace("#detailTable", "")
                    .Replace("#detailSortName", "")
                    .Replace("#DetailformOptions", "");
                EditFormContent = EditFormContent.Replace("#SubCondition", "");
                SubEditFormContent = SubEditFormContent.Replace("#ParentId", "NoId");
                EditFormContent = EditFormContent.Replace("#SubKeyword", "");
            }
            //表格页js
            savePath = Path.Combine(
                _solutionPath,
                "Coldairarrow.Web",
                "src",
                "views",
                areaName,
                entityName
                );

            //表单页          
            saveEditFormPath = Path.Combine(
                _solutionPath,
                "Coldairarrow.Web",
                "src",
                "views",
                areaName,
                entityName,
                "components"
                );


            //表单页          
            saveSubEditFormPath = Path.Combine(
                _solutionPath,
                "Coldairarrow.Web",
                "src",
                "views",
                areaName,
                entityName,
                "components"
                );

            //查询表单页          
            saveSearchFormPath = Path.Combine(
                _solutionPath,
                "Coldairarrow.Web",
                "src",
                "views",
                areaName,
                entityName,
                "components"
                );
            //table表单页          
            saveTableSettPath = Path.Combine(
                _solutionPath,
                "Coldairarrow.Web",
                "src",
                "views",
                areaName,
                entityName,
                "components"
                );
            //查询列表页          
            saveListFormPath = Path.Combine(
                _solutionPath,
                "Coldairarrow.Web",
                "src",
                "views",
                areaName,
                entityName
                );
            string tableName = sysTableInfo.TableName;

            pageContent = pageContent.Replace("#TableName", tableName);

            EditFormContent = EditFormContent.Replace("#IsKey", key);

            EditFormContent = EditFormContent.Replace("%areaName%", areaName);
            EditFormContent = EditFormContent.Replace("%entityName%", entityName);
            EditFormContent = EditFormContent.Replace("%SubentityName%", SubentityName);

            SubEditFormContent = SubEditFormContent.Replace("%areaName%", areaName);
            SubEditFormContent = SubEditFormContent.Replace("%SubentityName%", SubentityName);

            SearchFormContent = SearchFormContent.Replace("%areaName%", areaName);
            SearchFormContent = SearchFormContent.Replace("%entityName%", entityName);

            ListFormContent = ListFormContent.Replace("%areaName%", areaName);
            ListFormContent = ListFormContent.Replace("%entityName%", entityName);
            ListFormContent = ListFormContent.Replace("%IsKey%", key);

            TableSettContent = TableSettContent.Replace("%entityName%", entityName);
            TableSettContent = TableSettContent.Replace("%IsKey%", key);
            //生成vue数据结构js
            FileHelper.WriteFile($"{savePath}\\", "ranks.js", pageContent);

            //生成vue表单页面
            FileHelper.WriteFile($"{saveEditFormPath}\\", "EditForm.vue", EditFormContent);

            //生成vue子表单页面
            FileHelper.WriteFile($"{saveSubEditFormPath}\\", "SubForm.vue", SubEditFormContent);
           
            //生成vue表单页面
            FileHelper.WriteFile($"{saveSearchFormPath}\\", "SearchForm.vue", SearchFormContent);

            //生成vue表单页面
            FileHelper.WriteFile($"{saveListFormPath}\\", "List.vue", ListFormContent);

            //生成vue表单页面
            FileHelper.WriteFile($"{saveTableSettPath}\\", "TableSett.vue", TableSettContent);

            return "页面创建成功!";
        }

        public class SortField
        {
            public string field { get; set; }

            public string order { get; set; } = "desc";
           }

        /// <summary>
        /// 获取界面查询字段
        /// </summary>
        /// <param name="panelHtml"></param>
        /// <param name="sysColumnList"></param>
        /// <param name="vue"></param>
        /// <param name="edit"></param>
        /// <returns></returns>
        private List<object> GetSearchData(List<List<PanelHtml>> panelHtml, List<Sys_TableColumn> sysColumnList, bool vue = false, bool edit = false, bool app = false)
        {
            if (edit)
            {
                GetPanelData(sysColumnList, panelHtml, x => x.EditRowNo, c => c.EditRowNo != null && c.EditRowNo > 0, false, q => q.EditRowNo, true, false);
            }
            else
            {
                GetPanelData(sysColumnList, panelHtml, x => x.SearchRowNo, c => c.SearchRowNo != null, true, q => q.SearchRowNo, true, false);
            }

            List<object> list = new List<object>();

            int index = 0;
            bool group = panelHtml.Exists(x => x.Count > 1);
            panelHtml.ForEach(x =>
            {
                index++;
                List<Dictionary<string, object>> keyValuePairs = new List<Dictionary<string, object>>();
                //List<KeyValuePair<string, object>> keyValuePairs = new List<KeyValuePair<string, object>>();
                x.ForEach(s =>
                {
                    Dictionary<string, object> keyValues = new Dictionary<string, object>();
                    //if (vue)
                    //{
                        //  keyValues.Add("columnType", s.columnType);
                        if (!string.IsNullOrEmpty(s.dataSource) && s.dataSource != "''")
                        {
                            //if (app)
                            //{
                              keyValues.Add("key", s.dataSource);
                           // }
                            //else
                            //{
                            //    keyValues.Add("dataKey", s.dataSource);
                            //}
                            //2020.09.11增加vue页面数据源配置默认空数据源
                            keyValues.Add("data", new string[] { });
                        }
                        keyValues.Add("title", s.text);
                        //if (s.require)
                        //{
                        keyValues.Add("required", s.require);
                        keyValues.Add("message", "必填");
                        //}


                        keyValues.Add("field", s.id);
                        if (s.disabled)
                        {
                            keyValues.Add("disabled", true);
                        }
                        if (s.colSize > 0 && !app)
                        {
                            keyValues.Add("colSize", s.colSize);
                        }
                        if (!string.IsNullOrEmpty(s.displayType) && s.displayType != "''")
                        {
                            keyValues.Add("e_type", s.columnType == "img" ? s.columnType : s.displayType);
                        }
                        if (!string.IsNullOrEmpty(s.displayType) && (s.displayType =="switch"||s.displayType =="number"))
                        {
                            keyValues.Add("type", "number");
                        }
                        else
                        {
                            keyValues.Add("type", "string");
                        }
                    //}
                    //else
                    //{
                    //    keyValues.Add("columnType", s.columnType);
                    //    if (!string.IsNullOrEmpty(s.dataSource))
                    //    {
                    //        keyValues.Add("dataSource", s.dataSource);
                    //    }
                    //    keyValues.Add("text", s.text);
                    //    if (s.require)
                    //    {
                    //        keyValues.Add("require", s.require);
                    //    }
                    //    keyValues.Add("id", s.id);
                    //}
                    //if (!app)
                    //{
                    keyValuePairs.Add(keyValues);
                    //}
                    //else
                    //{
                    //    list.Add(keyValues);
                    //}
                });
                //if (!app)
                //{
                    list.Add(keyValuePairs);
                //}
                //else
                //{
                //    //app页面添加分组
                //    if (index != panelHtml.Count() && group)
                //    {
                //        list.Add(new { type = "group" });
                //    }
                //}
            });
            return list;
        }


        /// <summary>
        /// 生成查询面板的数据对象结构
        /// </summary>
        /// <param name="list"></param>
        /// <param name="panelHtml"></param>
        /// <param name="keySelector"></param>
        /// <param name="predicate"></param>
        /// <param name="search"></param>
        /// <param name="orderBy"></param>
        /// <param name="vue"></param>
        private void GetPanelData2(List<Sys_TableColumn> list, List<List<PanelHtml>> panelHtml, Func<Sys_TableColumn, int?> keySelector, Func<Sys_TableColumn, bool> predicate, bool search, Func<Sys_TableColumn, int?> orderBy, bool vue = false, bool app = false)
        {
            //{ key: 111, value: "显示/查询/编辑" },
            //{ key: 2, value: "显示/编辑" },
            //{ key: 3, value: "显示/查询" },
            //{ key: 4, value: "显示" },
            //{ key: 5, value: "查询/编辑" },
            //{ key: 6, value: "查询" },
            //{ key: 7, value: "编辑" },

            if (app)
            {
                list.ForEach(x =>
                {
                    if (x.EditRowNo == 0)
                    {
                        x.EditRowNo = 99999;
                    }
                });
                var arr = search ? new int[] { 1, 3, 5, 6 } : new int[] { 1, 2, 5, 7 };
                predicate = x => arr.Any(c => c == x.Enable);
            }

            var whereReslut = list.Where(predicate).OrderBy(orderBy).ThenByDescending(c => c.OrderNo).ToList();
            foreach (var item in whereReslut.GroupBy(keySelector))
            {
                panelHtml.Add(item.OrderBy(c => search ? c.SearchColNo : c.EditColNo).Select(
                    x => new PanelHtml
                    {
                        text = x.ColumnCnName ?? x.ColumnName,
                        id = x.ColumnName,
                        displayType = GetDisplayType(search, x.SearchType, x.EditType, x.ColumnType),
                        require = !search && x.IsNull == 0 ? true : false,
                        columnType = vue && x.IsImage == 1 ? "img" : (x.ColumnType ?? "string").ToLower(),
                        disabled = !search && x.IsReadDataset == 1 ? true : false,
                        dataSource = GetDropString(x.DropNo, vue),
                        colSize = search && x.SearchType != "checkbox" ? 0 : (x.ColSize ?? 0)
                    }).ToList());
            }
        }
        /// <summary>
        /// 生成查询面板的数据对象结构
        /// </summary>
        /// <param name="list"></param>
        /// <param name="panelHtml"></param>
        /// <param name="keySelector"></param>
        /// <param name="predicate"></param>
        /// <param name="search"></param>
        /// <param name="orderBy"></param>
        /// <param name="vue"></param>
        private void GetPanelData(List<Sys_TableColumn> list, List<List<PanelHtml>> panelHtml, Func<Sys_TableColumn, int?> keySelector, Func<Sys_TableColumn, bool> predicate, bool search, Func<Sys_TableColumn, int?> orderBy, bool vue = false, bool app = false)
        {
            //{ key: 111, value: "显示/查询/编辑" },
            //{ key: 2, value: "显示/编辑" },
            //{ key: 3, value: "显示/查询" },
            //{ key: 4, value: "显示" },
            //{ key: 5, value: "查询/编辑" },
            //{ key: 6, value: "查询" },
            //{ key: 7, value: "编辑" },

            if (app)
            {
                list.ForEach(x =>
                {
                    if (x.EditRowNo == 0)
                    {
                        x.EditRowNo = 99999;
                    }
                });
                var arr = search ? new int[] { 1, 3, 5, 6 } : new int[] { 1, 2, 5, 7 };
                predicate = x => arr.Any(c => c == x.Enable);
            }

            var whereReslut = list.Where(predicate).OrderBy(orderBy).ThenByDescending(c => c.OrderNo).ToList();
            foreach (var item in whereReslut.GroupBy(keySelector))
            {
                panelHtml.Add(item.OrderBy(c => search ? c.SearchColNo : c.EditColNo).Select(
                    x => new PanelHtml
                    {
                        text = x.ColumnCnName ?? x.ColumnName,
                        id = x.ColumnName,
                        displayType = GetDisplayType(search, x.SearchType, x.EditType, x.ColumnType),
                        require = !search && x.IsNull == 0 ? true : false,
                        columnType = vue && x.IsImage == 1 ? "img" : (x.ColumnType ?? "string").ToLower(),
                        disabled = !search && x.IsReadDataset == 1 ? true : false,
                        dataSource = GetDropString(x.DropNo, vue),
                        colSize = search && x.SearchType != "checkbox" ? 0 : (x.ColSize ?? 0)
                    }).ToList());
            }
        }
        private string GetDropString(string dropNo, bool vue)
        {
            if (string.IsNullOrEmpty(dropNo))
                return vue ? "''" : "__[]__";
            if (vue)
                return dropNo;
            return "__" + "optionConfig" + dropNo + "__";
        }
        private string GetDisplayType(bool search, string searchType, string editType, string columnType)
        {
            string type = "";
            if (search)
            {
                type = searchType == "无" ? "" : searchType ?? "";
            }
            else
            {
                type = editType == "无" ? "" : editType ?? "";
            }
            if (type == "" && formType.Contains(columnType))
            {
                if (columnType == "decimal" || columnType == "float")
                {
                    type = "decimal";
                }
                else
                {
                    type = "number";
                }
            }
            return type;
        }
        /// <summary>
        /// 生成表格的columns的配置信息
        /// </summary>
        /// <param name="list"></param>
        /// <param name="expressField"></param>
        /// <param name="detail"></param>
        /// <param name="vue"></param>
        /// <returns></returns>
        private StringBuilder GetGridColumns(List<Sys_TableColumn> list, string expressField, bool detail, bool vue = false, bool app = false)
        {
            totalCol = 0;
            totalWidth = 0;
            StringBuilder sb = new StringBuilder();

            //{ key: 1, value: "显示/查询/编辑" },
            //{ key: 2, value: "显示/编辑" },
            //{ key: 3, value: "显示/查询" },
            //{ key: 4, value: "显示" },
            //{ key: 5, value: "查询/编辑" },
            //{ key: 6, value: "查询" },
            //{ key: 7, value: "编辑" },
            Func<Sys_TableColumn, bool> func = x => true;
            bool sort = false;
            //if (app)
            //{
            //    func = x => new int[] { 1, 2, 3, 4 }.Any(c => c == x.Enable) && (x.IsDisplay == null || x.IsDisplay == 1);
            //}
            foreach (Sys_TableColumn item in list.Where(func).OrderByDescending(x => x.OrderNo))
            {
                string DisplayType = GetDisplayType(false, item.SearchType, item.EditType, item.ColumnType);
                if (item.IsColumnData == 0) { continue; }
                sb.Append("{dataIndex:'" + item.ColumnName + "',");
                sb.Append("{key:'" + item.ColumnName + "',");
                sb.Append("title:'" + (string.IsNullOrEmpty(item.ColumnCnName) ? item.ColumnName : item.ColumnCnName) + "',");
                //if (vue)
                //{
                    string colType = item.ColumnType.ToLower();
                    if (item.IsImage == 1)
                    {
                        colType = "img";
                    }
                    else if (item.IsImage == 2)
                    {
                        colType = "excel";
                    }
                    else if (item.IsImage == 3)
                    {
                        colType = "file";
                    }
                    //2021.07.27增加table列显示类型date(自动格式化)
                    else if (item.IsImage == 4)
                    {
                        colType = "date";
                    }
                
                    sb.Append("e_type:'" + item.ColumnType == "img" ? item.ColumnType : DisplayType + "',");
                //sb.Append("e_type:'" + colType + "',");
                    if (!string.IsNullOrEmpty(item.DropNo))
                    {
                        sb.Append("bind:{ key:'" + item.DropNo + "',data:[]},");
                    }
                    if (expressField != null && expressField.ToLower() == item.ColumnName.ToLower())
                    {
                        sb.Append("link:true,");
                    }
                    //2021.01.09增加代码生成器设置table排序功能
                    if (item.Sortable == 1 && !app)
                    {
                        sb.Append("sort:true,");
                    }
                //}
                //else
                //{
                //    sb.Append("datatype:'" + item.ColumnType + "',");
                //}

                //if (!app)
                //{
                    sb.Append("width:" + (item.ColumnWidth ?? 90) + ",");
                //}
                if (item.IsDisplay == 0)
                {
                    sb.Append("hidden:true,");
                }
                else
                {
                    totalCol++;
                    totalWidth += item.ColumnWidth == null ? 0 : Convert.ToInt32(item.ColumnWidth);
                }
                if (item.IsReadDataset == 1)
                {
                    sb.Append("readonly:true,");
                }
                //detail明细才启用表格编辑
                if (item.EditRowNo != null && item.EditRowNo > 0 && detail)//!string.IsNullOrEmpty(item.EditType))
                {
                    string editText = vue ? "edit" : "editor";
                    //if (vue)
                    //{
                        sb.Append("edit:{type:'" + item.EditType + "'},");
                    //}
                    //else
                    //{

                    //    switch (item.EditType)
                    //    {
                    //        case "date":
                    //            sb.Append("editor:'datebox',");
                    //            break;
                    //        case "datetime":
                    //            sb.Append("editor:'datetimebox',");
                    //            break;
                    //        case "drop":
                    //        case "dropList":
                    //        case "select":
                    //        case "selectList":
                    //            if (!vue && !string.IsNullOrEmpty(item.DropNo))
                    //            {
                    //                sb.Append(editText + ": { type: 'combobox', options: optionConfig" + item.DropNo + " },");
                    //            }
                    //            else
                    //            {
                    //                sb.Append(editText + ": 'text',");
                    //            }
                    //            break;
                    //        default:
                    //            sb.Append(editText + ":'text',");
                    //            break;
                    //    }
                    //}
                }
                //if (!vue)
                //{
                //    //快速查看字段
                //    if (expressField != null && expressField.ToLower() == item.ColumnName.ToLower())
                //    {
                //        sb.Append("formatter:function (val, row, index) { return $.fn.layOut('createViewField',{row:row,val:val,index:index})},");
                //    }
                //    else if (!string.IsNullOrEmpty(item.Script))
                //    {
                //        sb.Append("formatter:" + item.Script + ",");
                //    }
                //    else if (item.IsImage == 1)//启用图片
                //    {
                //        sb.Append("formatter:function (val, row, index) { return $.fn.layOut('createImageUrl',{row:row,key:'" + item.ColumnName + "'})},");
                //    }
                //    else if (!string.IsNullOrEmpty(item.DropNo) && !detail)
                //    {
                //        sb.AppendLine("formatter: function (val, row, index) {");
                //        sb.AppendLine(string.Format("    return dataSource{0}.textFormatter(optionConfig{0}, val, row, index);", item.DropNo));
                //        sb.AppendLine("    },");
                //    }
                //}

                if (item.IsNull == 0 && !app)
                {
                    sb.Append("required:true,");
                }

                if ( (item.ColumnType.ToLower() == "datetime" || (item.IsDisplay == 1 & !sort)))
                {
                    //2021.09.05修改排序名称
                    sb.Append("align:'left',sort:true},");
                    if (item.IsDisplay == 1)
                    {
                        sort = true;
                    }
                }
                else
                {
                    //if (!app)
                    //{
                        sb.Append("align:'left'},");
                    //}
                }
                //if (app)
                //{
                //    sb.Append("},").Replace(",},", "},");
                //}

                sb.AppendLine();
                sb.Append("                       ");
            }
            return sb;
        }

        private DbHelper GetTheDbHelper(string linkId)
        {
            var theLink = GetTheLink(linkId);
            DbHelper dbHelper = DbHelperFactory.GetDbHelper(theLink.DbType.ToEnum<DatabaseType>(), theLink.ConnectionStr);

            return dbHelper;
        }
        private Base_DbLink GetTheLink(string linkId)
        {
            Base_DbLink resObj = new Base_DbLink();
            var theModule = Db.GetIQueryable<Base_DbLink>().Where(x => x.Id == linkId).FirstOrDefault();
            resObj = theModule ?? resObj;

            return resObj;
        }
        public static string Serialize(object obj, JsonSerializerSettings formatDate = null)
        {
            if (obj == null) return null;
            formatDate = formatDate ?? new JsonSerializerSettings
            {
                DateFormatString = "yyyy-MM-dd HH:mm:ss"
            };
            return JsonConvert.SerializeObject(obj, formatDate);
        }
        /// <summary>
        /// 生成伪接口
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public string BuildSuperCodeToOpenAPI(BuildSuperInputDTO input)
        {
            var sysTableInfo = input.sys_Table;
            if (sysTableInfo == null
                || sysTableInfo.TableColumns == null
                || sysTableInfo.TableColumns.Count == 0)
                return "提交的配置数据不完整";
            string CName = input.sys_Table.CnName;
            string linkId = input.linkId;
            int Table_Id = input.sys_Table.Table_Id;
            string areaName = input.sys_Table.FolderName;
            string aTable = input.sys_Table.TableName;
            List<int> buildTypes = input.buildTypes;
            _areaName = areaName;
            //内部成员初始化
            _dbHelper = GetTheDbHelper();
            var tableColumn = Db.GetIQueryable<Sys_TableColumn>().Where(x => x.Table_Id == Table_Id && x.TableName ==input.sys_Table.TableName).ToList();
            if (tableColumn.Count == 0)
            {
                return $"没有查到{input.sys_Table.TableName}表信息";
            }

            if (string.IsNullOrEmpty(areaName))
            {
                return $"项目文件夹不能为空";
            }
            //实体名
            string entityName = aTable;
            //业务逻辑参数名
            string busName = $"{entityName.ToFirstLowerStr()}Bus";
            //业务逻辑变量名
            string _busName = $"_{busName}";
            List<string> selectOptionsList = new List<string>();
            List<string> listColumnsList = new List<string>();
            List<string> formColumnsList = new List<string>();
            tableColumn.Where(x => !ignoreProperties.Contains(x.ColumnName)).ToList().ForEach(aField =>
            {
                if (_dbHelper.DbTypeStr_To_CsharpType(aField.ColumnType) == typeof(string))
                    selectOptionsList.Add(
    $"                <a-select-option key=\"{aField.ColumnName}\">{aField.ColumnCnName}</a-select-option>");
                listColumnsList.Add(
    $"  {{ title: '{aField.ColumnCnName}', dataIndex: '{aField.ColumnName}', width: '10%' }},");
                formColumnsList.Add(
    $@"        <a-form-model-item label=""{aField.ColumnCnName}"" prop=""{aField.ColumnName}"">
          <a-input v-model=""entity.{aField.ColumnName}"" autocomplete=""off"" />
        </a-form-model-item>");
                Dictionary<string, string> renderParamters = new Dictionary<string, string>
                {
                        {$"%{nameof(areaName)}%",areaName },
                        {$"%{nameof(entityName)}%",entityName },
                        {$"%{nameof(busName)}%",busName },
                        {$"%{nameof(_busName)}%",_busName },
                        {$"%selectOptions%",string.Join("\r\n",selectOptionsList) },
                        {$"%listColumns%",string.Join("\r\n",listColumnsList) },
                        {$"%formColumns%",string.Join("\r\n",formColumnsList) }
                };

                //buildTypes,实体层=0,业务层=1,接口层=2,页面层=3
                //实体层
                //if (buildTypes.Contains(0))
                //{
                //    BuildEntity(tableColumn, CName, sysTableInfo);
                //}
                string tmpFileName = string.Empty;
                string savePath = string.Empty;
                //业务层
                if (buildTypes.Contains(1))
                {
                    //接口
                    tmpFileName = "NewIBusiness.txt";
                    savePath = Path.Combine(
                        _solutionPath,
                        "Coldairarrow.IBusiness",
                        areaName,
                        $"I{entityName}Business.cs");
                    WriteCode(renderParamters, tmpFileName, savePath);

                    //实现
                    tmpFileName = "NewBusiness.txt";
                    savePath = Path.Combine(
                        _solutionPath,
                        "Coldairarrow.Business",
                        areaName,
                        $"{entityName}Business.cs");
                    WriteCode(renderParamters, tmpFileName, savePath);
                }
                //接口层
                if (buildTypes.Contains(2))
                {
                    tmpFileName = "NewController.txt";
                    savePath = Path.Combine(
                        _solutionPath,
                        "Coldairarrow.Api",
                        "Controllers",
                        areaName,
                        $"{entityName}Controller.cs");
                    WriteCode(renderParamters, tmpFileName, savePath);
                }

            });

            return "";
        }
    }
 
}


